/**密码验证 */
export const passwordValidate = (_: any, value: any) => {
  const reg = /^[0-9a-zA-Z_()`!@#$%^&*_\-+=|{}[\]:;'<>,.?]{8,20}$/

  if (!value) {
    return new Error('请输入密码')
  }
  if (!reg.test(value)) {
    return new Error(
      '请输入8-20个字符，可包含英文字母、数字和标点符号（除空格）'
    )
  }
  return true
}

/**用户验证 */
export const accountValidate = (_, value: any) => {
  const reg = /^[0-9A-Za-z_@]{4,18}$/
  if (!value) {
    return new Error('请输入账号')
  }
  if (!reg.test(value)) {
    return new Error('请输入4-18个字符，可包含英文字母、数字、下划线')
  }
  return true
}

/**主机记录（域名前缀） */
export const hostValidate =
  (domainsFn?: RefSource<string>) => (_, value: string) => {
    const domains = domainsFn ? getSource(domainsFn) : ref('')
    // 换成小写验证
    value = value.toLowerCase().trim()

    if (value === '@') return true

    if (value.includes('..')) {
      return new Error('解析名不能包含连续的两个点')
    }

    if (value.includes('--')) {
      return new Error('解析名不能包含连续的两个“-”')
    }

    // 解析名只允许一个'*'
    if (value.includes('*') && value.split('*').length > 2) {
      return new Error('解析名只允许一个“*”')
    }
    // 解析名'*'只允许在首位
    if (value.includes('*') && value.indexOf('*') !== 0) {
      return new Error('解析名“*”只允许在首位')
    }

    // 解析名不能以“.”开头或结尾
    if (
      value.includes('.') &&
      (value.indexOf('.') === value.length - 1 ||
        value.indexOf('.') === 0 ||
        value.slice(-1) === '.')
    ) {
      return new Error('解析名不能以“.”开头或结尾')
    }

    // 解析名'*'后面只允许跟'.' 现版本支持多级解析域名暂时注释
    // if (value.includes('*') && value.length > 1) {
    //   return new Error('解析名“*”后面只允许跟“.”')
    // }
    // 解析名只能出现单个'@'
    if (value.includes('@') && value.split('@').length > 2) {
      return new Error('解析名只能出现单个“@”')
    }

    const mainDomain = history.state.domain as string

    const d = domainsFn ? getTrimValue(domains.value) : [mainDomain]

    if (d.length > 0) {
      for (const item of d) {
        const domain = `${value}.${item}`
        if (domain.length > 253) {
          return new Error('域名总长度不能超过253个字符')
        }
      }
    }

    const split = value
      .split('.')
      .filter(item => item && item !== '*') as string[]

    for (const item of split) {
      if (!domainSplitReg.test(item)) {
        return new Error(
          '每一级域名为字母、数字、“-”、“_”的组合且长度不能超过63字符'
        )
      }

      if (item.startsWith('-') || item.endsWith('-')) {
        return new Error('每一级域名不能以“-”开头或结尾')
      }
    }

    return true
  }

/**记录值 */
export const logValueValidate =
  (typeFn: RefSource<string>) => (_, value: string) => {
    const type = getSource(typeFn)

    if (type.value === 'MX') {
      if (!ipv4Reg.test(value) && !domainReg.test(value)) {
        return new Error('MX记录的记录值为域名或者IP形式')
      }
    }
    if (['CNAME', 'NS'].includes(type.value!)) {
      if (value.length > 253) {
        return new Error('域名总长度不能超过253个字符')
      }

      if (value.includes('.')) {
        const split = value.split('.').filter(item => item) as string[]

        for (const item of split) {
          if (!domainSplitReg.test(item)) {
            return new Error(
              '每一级域名为字母、数字、“-”、“_”的组合且长度不能超过63字符'
            )
          }
        }
      }

      if (!domainReg.test(value)) {
        return new Error('记录值为域名形式（如abc.example.com）')
      }
    }

    if (type.value === 'A') {
      if (!ipv4Reg.test(value)) {
        return new Error('记录值为IPv4形式')
      }
    }

    if (type.value === 'AAAA') {
      if (!ipv6Reg.test(value)) {
        return new Error('记录值为IPv6形式')
      }
    }

    if (type.value === 'TXT') {
      const reg = /^[0-9a-zA-Z.@!^%?#$&*()-+~_:"| -\\]{1,255}$/
      if (!reg.test(value)) {
        return new Error(
          '记录值长度限制255个字符，可以填写字母、数字和英文符号'
        )
      }
    }

    if (type.value === 'CAA') {
      const split = value.split(' ').filter(Boolean) as string[]
      const throwError = () =>
        new Error('记录值的格式为 <flags> <tag> <value> 如 0 issue "baidu.com"')
      if (split.length !== 3) {
        return throwError()
      }

      // 0 issue "amazonaws.com"111
      const lastItem = split[2]
      if (lastItem.split('"').filter(Boolean).length != 1) {
        return throwError()
      }

      const flags = split[0]
      const tag = split[1]
      const val = split[2]
      // 0-255正整数
      const flagsReg = /^[0-9]{1,3}$/
      if (!flagsReg.test(flags) || Number(flags) > 255) {
        return new Error('<flags>：认证机构限制标志，0~255无符号整型')
      }
      const tagList = ['issue', 'issuewild', 'iodef']
      if (!tagList.includes(tag)) {
        return new Error(
          `<tag>：证书属性标签，只能为 ${tagList.join('、')}之一`
        )
      }

      if (val.includes("'")) {
        return new Error(`<value>：只能双引号，或者没有引号`)
      }
      const domain = val.replace(/"/g, '')
      if (!domainReg.test(domain)) {
        return new Error(`<value>：只能为域名形式`)
      }
    }
    return true
  }
